﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace SafeLoad.NControl
{
    /// <summary>
    /// NPipeLineThree.xaml 的交互逻辑
    /// </summary>
    public partial class NPipeLineThree : UserControl
    {
		public NPipeLineThree()
		{
			InitializeComponent();
		}

		/// <summary>
		/// 获取或设置管道控件的边缘颜色
		/// </summary>
		public Color EdgeColor
		{
			get { return (Color)GetValue(EdgeColorProperty); }
			set { SetValue(EdgeColorProperty, value); }
		}

		// Using a DependencyProperty as the backing store for EdgeColor.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty EdgeColorProperty =
			DependencyProperty.Register("EdgeColor", typeof(Color), typeof(NPipeLineThree), new PropertyMetadata(Colors.LightGray));

		/// <summary>
		/// 管道的中心颜色
		/// </summary>
		public Color CenterColor
		{
			get { return (Color)GetValue(CenterColorProperty); }
			set { SetValue(CenterColorProperty, value); }
		}

		// Using a DependencyProperty as the backing store for CenterColor.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty CenterColorProperty =
			DependencyProperty.Register("CenterColor", typeof(Color), typeof(NPipeLineThree), new PropertyMetadata(Colors.LightGray));

		/// <summary>
		/// 获取或设置管道1号线是否激活液体显示
		/// </summary>
		public bool PipeLineActive1
		{
			get { return (bool)GetValue(PipeLineActive1Property); }
			set { SetValue(PipeLineActive1Property, value); }
		}

		// Using a DependencyProperty as the backing store for PipeLineActive1.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty PipeLineActive1Property =
			DependencyProperty.Register("PipeLineActive1", typeof(bool), typeof(NPipeLineThree), 
				new PropertyMetadata(false, new PropertyChangedCallback(MoveSpeed1PropertyChangedCallback)));

		/// <summary>
		/// 获取或设置管道2号线是否激活液体显示
		/// </summary>
		public bool PipeLineActive2
		{
			get { return (bool)GetValue(PipeLineActive2Property); }
			set { SetValue(PipeLineActive2Property, value); }
		}

		// Using a DependencyProperty as the backing store for PipeLineActive2.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty PipeLineActive2Property =
			DependencyProperty.Register("PipeLineActive2", typeof(bool), typeof(NPipeLineThree), 
				new PropertyMetadata(false, new PropertyChangedCallback(MoveSpeed2PropertyChangedCallback)));

		/// <summary>
		/// 获取或设置管道3号线是否激活液体显示
		/// </summary>
		public bool PipeLineActive3
		{
			get { return (bool)GetValue(PipeLineActive3Property); }
			set { SetValue(PipeLineActive3Property, value); }
		}

		// Using a DependencyProperty as the backing store for PipeLineActive3.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty PipeLineActive3Property =
			DependencyProperty.Register("PipeLineActive3", typeof(bool), typeof(NPipeLineThree), new PropertyMetadata(false, 
				new PropertyChangedCallback(MoveSpeed3PropertyChangedCallback)));

		/// <summary>
		/// 获取或设置管道1号线液体流动的速度，0为静止，正数为正向流动，负数为反向流动
		/// </summary>
		public double MoveSpeed1
		{
			get { return (double)GetValue(MoveSpeed1Property); }
			set { SetValue(MoveSpeed1Property, value); }
		}

		// Using a DependencyProperty as the backing store for MoveSpeed1.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty MoveSpeed1Property =
			DependencyProperty.Register("MoveSpeed1", typeof(double), typeof(NPipeLineThree),
				new PropertyMetadata(0d, new PropertyChangedCallback(MoveSpeed1PropertyChangedCallback)));

		public static void MoveSpeed1PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		{
			NPipeLineThree pipeThree = (NPipeLineThree)dependency;
			pipeThree.MoveSpeedOrActiveChanged1();
		}

		private DoubleAnimation offect1DoubleAnimation = null;
		private void MoveSpeedOrActiveChanged1()
        {
			MoveSpeedOrActiveChanged(PipeLineActive1, MoveSpeed1, ref offect1DoubleAnimation, LineOffect1Property);
        }
		private void MoveSpeedOrActiveChanged2()
		{
			MoveSpeedOrActiveChanged(PipeLineActive2, MoveSpeed2, ref offect2DoubleAnimation, LineOffect2Property);
		}
		private void MoveSpeedOrActiveChanged3()
		{
			MoveSpeedOrActiveChanged(PipeLineActive3, MoveSpeed3, ref offect3DoubleAnimation, LineOffect3Property);
		}

		private void MoveSpeedOrActiveChanged(bool lineActive, double moveSpeed, 
			ref DoubleAnimation animation, DependencyProperty offectProperty)
        {
			if (!lineActive)
            {
				//取消动画
				if (animation != null)
                {
					BeginAnimation(offectProperty, null);
					animation = null;
                }
				return;
            }

			if (Math.Abs(moveSpeed) < 0.001)
            {
				//moveSpeed等于0， 停止动画
				if (animation != null)
                {
					BeginAnimation(offectProperty, null);
					animation = null;
                }
            }
			else if (moveSpeed > 0)
            {
				animation = new DoubleAnimation(0d, 10d, TimeSpan.FromMilliseconds(300 / Math.Abs(moveSpeed)));
				animation.RepeatBehavior = RepeatBehavior.Forever;
				BeginAnimation(offectProperty, animation);
            }
			else
            {
				animation = new DoubleAnimation(0d, -10d, TimeSpan.FromMilliseconds(300 / Math.Abs(moveSpeed)));
				animation.RepeatBehavior = RepeatBehavior.Forever;
				BeginAnimation(offectProperty, animation);
            }
        }

		/// <summary>
		/// 获取或设置管道2号线液体流动的速度，0为静止，正数为正向流动，负数为反向流动
		/// </summary>
		public double MoveSpeed2
		{
			get { return (double)GetValue(MoveSpeed2Property); }
			set { SetValue(MoveSpeed2Property, value); }
		}

		// Using a DependencyProperty as the backing store for MoveSpeed2.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty MoveSpeed2Property =
			DependencyProperty.Register("MoveSpeed2", typeof(double), typeof(NPipeLineThree),
				new PropertyMetadata(0d, new PropertyChangedCallback(MoveSpeed2PropertyChangedCallback)));

		public static void MoveSpeed2PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		{
			NPipeLineThree pipeLine = (NPipeLineThree)dependency;
			pipeLine.MoveSpeedOrActiveChanged2();
		}

		private DoubleAnimation offect2DoubleAnimation = null;

		/// <summary>
		/// 获取或设置管道3号线液体流动的速度，0为静止，正数为正向流动，负数为反向流动
		/// </summary>
		public double MoveSpeed3
		{
			get { return (double)GetValue(MoveSpeed3Property); }
			set { SetValue(MoveSpeed3Property, value); }
		}

		// Using a DependencyProperty as the backing store for MoveSpeed3.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty MoveSpeed3Property =
			DependencyProperty.Register("MoveSpeed3", typeof(double), typeof(NPipeLineThree),
				new PropertyMetadata(0d, new PropertyChangedCallback(MoveSpeed3PropertyChangedCallback)));

		public static void MoveSpeed3PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		{
			NPipeLineThree pipeLine = (NPipeLineThree)dependency;
			pipeLine.MoveSpeedOrActiveChanged3();
		}

		private DoubleAnimation offect3DoubleAnimation = null;

		/// <summary>
		/// 管道1的偏移
		/// </summary>
		public double LineOffect1
		{
			get { return (double)GetValue(LineOffect1Property); }
			set { SetValue(LineOffect1Property, value); }
		}

		// Using a DependencyProperty as the backing store for LineOffect1.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty LineOffect1Property =
			DependencyProperty.Register("LineOffect1", typeof(double), typeof(NPipeLineThree), new PropertyMetadata(0d));

		/// <summary>
		/// 管道2的偏移
		/// </summary>
		public double LineOffect2
		{
			get { return (double)GetValue(LineOffect2Property); }
			set { SetValue(LineOffect2Property, value); }
		}

		// Using a DependencyProperty as the backing store for LineOffect2.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty LineOffect2Property =
			DependencyProperty.Register("LineOffect2", typeof(double), typeof(NPipeLineThree), new PropertyMetadata(0d));

		/// <summary>
		/// 管道3的偏移
		/// </summary>
		public double LineOffect3
		{
			get { return (double)GetValue(LineOffect3Property); }
			set { SetValue(LineOffect3Property, value); }
		}

		// Using a DependencyProperty as the backing store for LineOffect3.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty LineOffect3Property =
			DependencyProperty.Register("LineOffect3", typeof(double), typeof(NPipeLineThree), new PropertyMetadata(0d));



		/// <summary>
		/// 获取或设置中间管道线的宽度信息，默认为3
		/// </summary>
		public int PipeLineWidth
		{
			get { return (int)GetValue(PipeLineWidthProperty); }
			set { SetValue(PipeLineWidthProperty, value); }
		}

		// Using a DependencyProperty as the backing store for PipeLineWidth.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty PipeLineWidthProperty =
			DependencyProperty.Register("PipeLineWidth", typeof(int), typeof(NPipeLineThree), new PropertyMetadata(2));

		/// <summary>
		/// 获取或设置流动状态时管道控件的中心颜色
		/// </summary>
		public Color ActiveLineCenterColor
		{
			get { return (Color)GetValue(ActiveLineCenterColorProperty); }
			set { SetValue(ActiveLineCenterColorProperty, value); }
		}

		// Using a DependencyProperty as the backing store for ActiveLineCenterColor.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty ActiveLineCenterColorProperty =
			DependencyProperty.Register("ActiveLineCenterColor", typeof(Color), typeof(NPipeLineThree), new PropertyMetadata(Colors.DodgerBlue));

		/// <summary>
		/// 获取或设置管道的宽度，默认为30
		/// </summary>
		public int PipeWidth
		{
			get { return (int)GetValue(PipeWidthProperty); }
			set { SetValue(PipeWidthProperty, value); }
		}

		// Using a DependencyProperty as the backing store for PipeWidth.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty PipeWidthProperty =
			DependencyProperty.Register("PipeWidth", typeof(int), typeof(NPipeLineThree),
				new PropertyMetadata(30, new PropertyChangedCallback(PipeWidthPropertyChangedCallback)));


		public static void PipeWidthPropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		{
			NPipeLineThree pipeLine = (NPipeLineThree)dependency;
			pipeLine.UpdatePath();
		}

		protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
		{
			UpdatePath();
			base.OnRenderSizeChanged(sizeInfo);
		}

		private void UpdatePath()
		{
			polygon1.Points = new PointCollection(new Point[]
			{
				new Point(ActualWidth / 2 - PipeWidth / 2d, PipeWidth),
				new Point(ActualWidth / 2, PipeWidth / 2d),
				new Point(ActualWidth / 2 + PipeWidth / 2d, PipeWidth),
				new Point(ActualWidth / 2 + PipeWidth / 2d, ActualHeight),
				new Point(ActualWidth / 2 - PipeWidth / 2d, ActualHeight),
				new Point(ActualWidth / 2 - PipeWidth / 2d, PipeWidth),
			});

			var g1 = new StreamGeometry();
			using (StreamGeometryContext context = g1.Open())
			{
				context.BeginFigure(new Point(0, PipeWidth / 2d), false, false);
				context.LineTo(new Point(ActualWidth, PipeWidth / 2d), true, false);
			}
			path1.Data = g1;

			var g2 = new StreamGeometry();
			using (StreamGeometryContext context = g2.Open())
			{
				context.BeginFigure(new Point(0, PipeWidth / 2d), false, false);
				context.LineTo(new Point(ActualWidth / 2 - PipeWidth / 2d, PipeWidth / 2d), true, false);
				context.ArcTo(new Point(ActualWidth / 2, PipeWidth), new Size(PipeWidth / 2d, PipeWidth / 2d), 0, false, SweepDirection.Clockwise, true, false);
				context.LineTo(new Point(ActualWidth / 2, ActualHeight), true, false);
			}
			path2.Data = g2;

			var g3 = new StreamGeometry();
			using (StreamGeometryContext context = g3.Open())
			{
				context.BeginFigure(new Point(ActualWidth, PipeWidth / 2d), false, false);
				context.LineTo(new Point(ActualWidth / 2 + PipeWidth / 2d, PipeWidth / 2d), true, false);
				context.ArcTo(new Point(ActualWidth / 2, PipeWidth), new Size(PipeWidth / 2d, PipeWidth / 2d), 0, false, SweepDirection.Counterclockwise, true, false);
				context.LineTo(new Point(ActualWidth / 2, ActualHeight), true, false);
			}
			path3.Data = g3;


		}
	}
}
